package main.scala
   
import scala.util.parsing.combinator.PackratParsers
import scala.util.parsing.combinator.RegexParsers


trait Parser extends RegexParsers with PackratParsers {
  
   import AST._

   lazy val start : PackratParser[Exp] =
    phrase (exp)
    
   lazy val exp : PackratParser[Exp] =
   	exp ~ ("+" ~> term) ^^ { case e ~ t => BAdd (e, t) } |
   	exp ~ ("-" ~> term) ^^ { case e ~ t => BSub (e, t) } |
   	 ("-" ~> term) ^^ { case t => Neg (t) } |
   	term
   
   lazy val term : PackratParser[Exp] =
   	term ~ ("*" ~> factor) ^^ { case t ~ f => BMul (t, f) } |
   	term ~ ("/" ~> factor) ^^ { case t ~ f => BDiv (t, f) } |
   	term ~ ("%" ~> factor) ^^ { case e ~ t => Mod (e, t) } |
   	power

   lazy val power : PackratParser[Exp] =
   	power ~ ("^" ~> factor) ^^ { case e ~ t => Pow (e, t) } |
   	factor

   lazy val factor : PackratParser[Exp] =
   	double | integer | variable | power |"-" ~> exp ^^ Neg | "(" ~> exp <~ ")"

   lazy val double : PackratParser[NumD] =
   	"""[0-9]+\.[0-9]+""".r ^^ (s => NumD (s.toDouble))

   lazy val integer : PackratParser[NumI] =
   	"[0-9]+".r ^^ (s => NumI (s.toInt))

   lazy val variable : PackratParser[Var] =
   	idn ^^ Var

   lazy val idn : PackratParser[String] =
//   	not (keyword) ~> "[a-zA-Z][a-zA-Z0-9]*".r
	   Parser("[a-zA-Z][a-zA-Z0-9]*".r)
	
}